package com.atguigu.myrule;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * The CustomConfiguration class must be a @Configuration class,
 * but take care that it is not in a @ComponentScan for the main application context.
 * Otherwise, it is shared by all the @RibbonClients.
 * If you use @ComponentScan (or @SpringBootApplication),
 * you need to take steps to avoid it being included
 * (for instance, you can put it in a separate, non-overlapping package or
 * specify the packages to scan explicitly in the @ComponentScan).
 *
 * 自定义的ribbon规则不能被@ComponentScan扫描到，只能通过@RibbonClient来引入
 * 自定义ribbon rule
 * @author timiv
 */
public class MyRule implements IRule {

    private ILoadBalancer loadBalancer;

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public Server choose(Object key) {
        List<Server> allServers = loadBalancer.getReachableServers();
        int current = atomicInteger.get();
        int next = current + 1;
        int index = getNext(current,next);
        return allServers.get(index % allServers.size());
    }

    private final int getNext(int current,int next){
        while (!atomicInteger.compareAndSet(current,next)){
            next = next > Integer.MAX_VALUE?0:atomicInteger.get()+1;
        }

        return next;
    }

    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
        loadBalancer = lb;
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
        return loadBalancer;
    }

    /*@Override
    public void setLoadBalancer(ILoadBalancer lb) {
        loadBalancer = lb;
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
        return loadBalancer;
    }*/
}
